1 module hip.event.handlers.input_listener;
2 public import hip.api.input.button;
3 public import hip.api.input.keyboard;
4 public import hip.api.input.mouse;
5 import hip.api.input.core : IHipInputListener;
6 import hip.event.dispatcher;
7 import hip.event.handlers.keyboard;
8 import hip.event.handlers.mouse;
9 import hip.util.string;
10 
11 String str(const(HipButton)* btn)
12 {
13     return String("Button ", btn.id, " ",btn.type, "  [autoremove: ", btn.isAutoRemove, "]");
14 }
15 
16 class HipInputListener : IHipInputListener
17 {
18     protected HipButton[] touchListeners;
19     protected HipButton[] keyboardListeners;
20 
21     protected ScrollListener[] scrollListeners;
22     protected TouchMoveListener[] moveListeners;
23 
24     protected KeyboardHandler keyboard;
25     protected HipMouse mouse;
26 
27     this(EventDispatcher dispatcher)
28     {
29         this.keyboard = dispatcher.keyboard;
30         this.mouse = dispatcher.mouse;
31     }
32 
33     const(HipButton)* addKeyboardListener(HipKey key, 
34         HipInputAction action,
35         HipButtonType type = HipButtonType.down,
36         AutoRemove remove = AutoRemove.no
37         )
38     {
39         keyboardListeners~= HipButton(cast(ushort)key, type, remove, action);
40         
41         return &keyboardListeners[$-1];
42     }
43 
44     const(HipButton)* addTouchListener(HipMouseButton btn, 
45         HipInputAction action,
46         HipButtonType type = HipButtonType.down,
47         AutoRemove remove = AutoRemove.no
48         )
49     {
50         touchListeners~= HipButton(cast(ushort)btn, type, remove, action);
51         return &touchListeners[$-1];
52     }
53 
54     const(ScrollListener)* addScrollListener(HipScrollAction onScroll, AutoRemove isAutoRemove = AutoRemove.no)
55     {
56         scrollListeners~= ScrollListener(onScroll, isAutoRemove);
57         return &scrollListeners[$-1];
58     }
59     const(TouchMoveListener)* addTouchMoveListener(HipTouchMoveAction onTouchMove, AutoRemove isAutoRemove = AutoRemove.no)
60     {
61         moveListeners~= TouchMoveListener(onTouchMove, isAutoRemove);
62         return &moveListeners[$-1];
63     }
64 
65     /**
66     *   Mainly used for the scriptInputListener
67     */
68     void clearAll()
69     {
70         import hip.console.log;
71         hiplog("Clearing all input events.");
72         touchListeners.length = 0;
73         scrollListeners.length = 0;
74         moveListeners.length = 0;
75         keyboardListeners.length = 0;
76     }
77 
78     import hip.util.array:remove;
79     bool removeKeyboardListener(const(HipButton)* button)
80     {
81         import hip.console.log;
82         hiplog("Removing keyboard listener ", button.str);
83         return remove(keyboardListeners, button);
84     }
85     bool removeTouchListener(const(HipButton)* button)
86     {
87         import hip.console.log;
88         hiplog("Removing touch listener f ", button.str);
89         return remove(touchListeners, button);
90     }
91     bool removeScrollListener(const(ScrollListener)* onScroll)
92     {
93         import hip.console.log;
94         hiplog("Removing scroll listener ");
95         return remove(scrollListeners, onScroll);
96     }
97     bool removeTouchMoveListener(const(TouchMoveListener)* onTouchMove)
98     {
99         import hip.console.log;
100         hiplog("Removing touch move listener ");
101         return remove(moveListeners, onTouchMove);
102     }
103 
104     void update()
105     {
106         foreach(ref key; keyboardListeners)
107         {
108             bool shouldExecute = false;
109             final switch(key.type) with(HipButtonType)
110             {
111                 case down:
112                     shouldExecute = keyboard.isKeyJustPressed(cast(char)key.id);
113                     break;
114                 case up:
115                     shouldExecute = keyboard.isKeyJustReleased(cast(char)key.id);
116                     break;
117             }
118             if(shouldExecute)
119             {
120                 key.action(keyboard.getMetadata(cast(char)key.id));
121                 if(key.isAutoRemove)
122                     removeKeyboardListener(&key);
123             }
124         }
125 
126         if(mouse.getDeltaPosition().magSquare != 0)
127         {
128             import hip.api.input.core;
129             import hip.console.log;
130             float[2] pos = HipInput.getWorldTouchPosition();
131             int x = cast(int)pos[0], y = cast(int)pos[1];
132             foreach(ref move; moveListeners)
133             {
134                 move.action(x, y);
135                 if(move.isAutoRemove)
136                     removeTouchMoveListener(&move);
137             }
138         }
139         auto scroll = mouse.getScroll();
140         if(scroll.magSquare != 0)
141         {
142             foreach(ref listener; scrollListeners)
143             {
144                 listener.action(cast(float[3])scroll);
145                 if(listener.isAutoRemove)
146                     removeScrollListener(&listener);
147             }
148         }
149 
150         foreach(ref touch; touchListeners)
151         {
152             bool shouldExecute = false;
153             final switch(touch.type) with(HipButtonType)
154             {
155                 case down:
156                     shouldExecute = mouse.isJustPressed(cast(HipMouseButton)touch.id);
157                     break;
158                 case up:
159                     shouldExecute = mouse.isJustReleased(cast(HipMouseButton)touch.id);
160                     break;
161             }
162             if(shouldExecute)
163             {
164                 touch.action(mouse.getMetadata(cast(HipMouseButton)touch.id));
165                 if(touch.isAutoRemove)
166                     removeTouchListener(&touch);
167             }
168         }
169     }
170 }